#include "tcp_socket.hpp"
#include"signal.h"
int new_worker(TcpSocket &conn_sock)
{
  pid_t pid = fork();
  if(pid < 0){
    perror("fork error");
    return -1;
  }else if(pid == 0){  // 子进程进入
    while(1){
      std::string buf;
      bool ret = conn_sock.Recv(&buf);
      if(ret == false){
        conn_sock.Close();
        break; //接收信息错误直接退出循环
      }
      std::cout<<"client say:"<<buf<<std::endl;
      std::cout<<"server say:";
      fflush(stdout);
      std::cin>>buf;
      ret = conn_sock.Send(buf);
      if(ret == false){
        conn_sock.Close();
        break; //接收信息错误直接退出循环
      }
    }
    conn_sock.Close();//关闭子进程套接字
    exit(-1); //子进程直接退出
  }
  return 0; //父进程退出该函数
}
int main()
{
    //显式忽略子进程退出信号，相当于告诉系统，子进程退出直接释放资源
    signal(SIGCHLD, SIG_IGN);
    TcpSocket lst_sock;
    //1. 创建套接字
    CHECK_RET(lst_sock.Socket());
    //2. 绑定地址信息
    CHECK_RET(lst_sock.Bind("192.168.197.128",3090));
    //3. 开始监听
    CHECK_RET(lst_sock.Listen());
    while(1){
        //4. 获取新建连接
        TcpSocket conn_sock;
        std::string client_ip;
        uint16_t client_port;
        bool ret = lst_sock.Accept(&conn_sock, &client_ip, &client_port);//此时conn_sock的成员_sockfd就是通信套接字。
        if (ret < 0) {
            continue;
        }
        std::cout << "new connect:" << client_ip << ":" << client_port << std::endl;
        //5. 通过新建连接与客户端通信
        new_worker(conn_sock);
        //父进程必须关闭套接字，否则连接的客户端越多，创建的套接字越多
        //但是父进程本质并不与客户端通信，所以最后资源会耗尽
        //因此必须关闭，而父子进程数据独有，因此父进程的关闭并不影响子进程
        conn_sock.Close();
    }
    //6. 关闭套接字
    lst_sock.Close();
    return 0;
}

